import {createElement, createTextNode} from "./vdom/index";
import {patch} from "./vdom/patch";

// 创造对应的虚拟节点 进行渲染
export function lifeCycleMixin(Vue) {

    Vue.prototype._c = function () {
        return createElement(this,...arguments);
    }
    Vue.prototype._v = function () {
        return createTextNode(this,...arguments);
    }
    // 将数据转换成字符串
    Vue.prototype._s = function (value) {
        if (typeof value == 'object' && value !== null) {
            return JSON.stringify(value);
        }
        return value;
    }

    // 调用生成的render函数
    Vue.prototype._render = function () {
        const vm = this;
        const render = vm.$options.render;
        let vnode = render.call(vm);
        return vnode;
    }
    // 将虚拟节点变成真实节点
    Vue.prototype._update = function (vnode) {
        // 将vnode渲染到el元素中
        const vm = this;
        let el = vm.$el;
        // 第一次可以初始化渲染，后续更新也走这个patch方法
        vm.$el = patch(el,vnode);
    }
}

// 将模板变成ast -> render -> render函数产生虚拟节点(数据得是渲染好的)
//      再次更新创建   |----> render函数产生

// 实现页面的挂载
export function mountComponent(vm, el) {
    // 现在el挂载到实例上
    vm.$el = el;
    // 挂载和更新都需要走这个流程
    const updateComponent = () => {
        // 需要调用生成的render函数 获取到虚拟节点 -> 生成真实dom
        vm._update(vm._render());
    };
    // 数据变化也调用这个函数，重新执行
    updateComponent();
    // 观察者模式  依赖收集  diff算法
}